// FXParser.cpp : Defines the entry point for the console application.
//

#include <antlr3.h>

#include "EffectDescriptorTypes.h"
#include "TechniqueLexer.h"
#include "TechniqueParser.h"

typedef std::string String;

using namespace std;

namespace RB
{
      void TechniqueError(pANTLR3_BASE_RECOGNIZER recognizer,
          pANTLR3_UINT8 * tokenNames) {}

      void TechniqueSetErrorString(std::string* e) {}
}

namespace FXParser
{
// Use the Technique grammar to parse an FX file from an in-memory,
// zero-terminted UTF8 string buffer.
bool ParseFxString(
    const String& fx_string,
    String *shader_string,
    FXDesc* fxDesc) 
{
  // Create a token stream from a zero-terminated memory buffer of uint8.
  ANTLR3_UINT32 fx_string_length =
      static_cast<ANTLR3_UINT32>(fx_string.length());
  if (fx_string_length == 0) 
  {
    return true;
  }

  // Create the input stream from the memory buffer.
  // The antlr3 stream library requires a non-const pointer to the fx_string.
  char* temp_fx_string = const_cast<char*>(fx_string.c_str());
  char* temp_name = const_cast<char*>("test_name");

  pANTLR3_INPUT_STREAM input_stream =
      antlr3StringStreamNew(
          reinterpret_cast<pANTLR3_UINT8>(temp_fx_string),
		  ANTLR3_ENC_8BIT,
          fx_string_length,
          reinterpret_cast<pANTLR3_UINT8>(temp_name));
  if (input_stream == NULL) 
  {
    return false;
  }

  // Create the language-specific Lexer.
  pTechniqueLexer lexer = TechniqueLexerNew(input_stream);
  if (lexer == NULL) 
  {
    input_stream->close(input_stream);
    return false;
  }

  // Create token stream from the Lexer.
  pANTLR3_COMMON_TOKEN_STREAM token_stream =
      antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, TOKENSOURCE(lexer));
  if (token_stream == NULL)  
  {
    lexer->free(lexer);
    input_stream->close(input_stream);
    return false;
  }

  // Force the token stream to turn off token filtering and pass all
  // whitespace and comments through to the parser.
  token_stream->discardOffChannel = ANTLR3_FALSE;

  // Create the language Parser.
  pTechniqueParser parser = TechniqueParserNew(token_stream);
  if (parser == NULL) 
  {
    token_stream->free(token_stream);
    lexer->free(lexer);
    input_stream->close(input_stream);
    return false;
  }
  string error_string;

  // call the root parsing rule to parse the input stream.
  bool return_value = parser->translation_unit(parser,
                                               fxDesc,
                                               shader_string,
                                               &error_string);
  // Free created objects.
  parser->free(parser);
  token_stream->free(token_stream);
  lexer->free(lexer);
  input_stream->close(input_stream);

  // Completed
  return return_value;
}

}
